#include "stdafx.h"

#include <windows.h>

#include "lock.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif



class LockObject::Impl
{
	mutable CRITICAL_SECTION cr;
#if defined(_DEBUG_LOCKOBJECT)
	mutable int m_LockCount;
	mutable char * m_LockerFile;
	mutable int m_LockerLine;
#endif
public:
	Impl()
#if defined(_DEBUG_LOCKOBJECT)
		: m_LockCount(0)
#endif
	{
		::InitializeCriticalSection( &cr );
	}
	~Impl()
	{
		::DeleteCriticalSection( &cr );
	}
#if defined(_DEBUG_LOCKOBJECT)
	void lock_object_dbg(char * szFile, int nLine) const
	{
//		ASSERT(0==m_LockCount);
		++m_LockCount;

		::EnterCriticalSection( &cr );

		m_LockerFile = szFile;
		m_LockerLine = nLine;
	};

	void unlock_object() const
	{
//		ASSERT(0<m_LockCount);
		--m_LockCount;

		m_LockerFile = NULL;
		m_LockerLine = 0;

		::LeaveCriticalSection( &cr );
	};
#else
	void lock_object() const
	{
		::EnterCriticalSection( &cr );
	};

	void unlock_object() const
	{
		::LeaveCriticalSection( &cr );
	};
#endif
};

#if defined(_DEBUG_LOCKOBJECT)
void LockObject::lock_object_dbg(char * szFile, int nLine) const
{
	impl->lock_object_dbg(szFile, nLine);
}
#else
void LockObject::lock_object()const
{
	impl->lock_object();
}
#endif

void LockObject::unlock_object()const
{
	impl->unlock_object();
}

LockObject::LockObject()
:	impl( new Impl )
{}

LockObject::LockObject(const LockObject & obj)
:	impl( new Impl )
{}

const LockObject & LockObject::operator=(const LockObject & obj)
{
	if( this != &obj )
	{
		// Do nothing - old impl is OK here
	}
	return *this;
}

LockObject::~LockObject()
{
	delete impl;
}
